<?php


namespace App\Helpers;


use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class Price
{
    var $zeros = ["0", "00", "000", "0000", "00000", "000000", "0000000", "00000000"];
    var $chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
            'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];

    private function encrypt($url, $b = 2, $e = true)
    {
        $number = $this->findNumber($url);
        $letter = $this->findLetter($url);
        $str = $letter . $number;
        $g = [];
        $u = new Utils();
        for ($i = 0; $i < strlen($str); $i++) {
            $g[] = $this->convert(
                $u->unicodeEncode($str, $i),
                $b
            );
        }
        $hy = implode('', $g);
        $yh = strrev($hy);
        $param = $e ? $yh : $hy;
        return $this->rnd($param, 4);
    }

    private function convert($a, $c)
    {
        $r = $this->round($a + 88, $c);
        $e = '' . base_convert($r, 10, 16);
        $f = $c - strlen($e);
        return $f > 0 ? $this->zeros[$f - 1] . $e : $e;
    }

    private function round($a, $b)
    {
        $c = 1 << 4 * $b;
        return 0 > $a ? $a % $c + $c : $a % $c;
    }

    private function findNumber($str)
    {
        $reg='/[0-9]+/';
        preg_match_all($reg, $str, $result);
        if(is_array($result) && !empty($result) && !empty($result[0])) {
            return implode('', $result[0]);
        }
        return '';
    }

    private function findLetter($str)
    {
        $str = str_replace('https', 'http', $str);
        $reg='/[a-zA-Z]+/';
        preg_match_all($reg, $str, $result);
        if(is_array($result) && !empty($result) && !empty($result[0])) {
            return implode('', $result[0]);
        }
        return '';
    }

    private function rnd($a, $b)
    {
        $rd = $this->rd($b);
        $hexMd5 = md5($a);
        return $rd . $hexMd5 . $this->rd(rand(0, 10));
    }

    private function rd($a)
    {
        $res = '';
        for ($i = 0; $i < $a; $i++) {
            $res .= $this->chars[rand(0, 35)];
        }
        return $res;
    }

    public function getPrice($url)
    {
        if (strpos($url, 'm.tb')) {
            // 淘宝链接获取目标地址
            $result = file_get_contents($url);
            $pattern = '#var url = \'(.*)\';#';
            preg_match($pattern, $result, $matches);
            $arr = explode('?', $matches[1]);
            $items = explode('&', $arr[1]);
            $id = '';
            foreach ($items as $item) {
                $temp = explode('=', $item);
                if ($temp[0] == 'id') {
                    $id = $temp[1];
                    break;
                }
            }
            $url = $arr[0] . '?id=' . $id;
        } elseif (strpos($url, 'm.jd')) {
            $arr = explode('?', $url);
            $url = $arr[0];
            $arr = explode('/', $url);
            $url = 'https://item.jd.com/' . $arr[count($arr) - 1];
        }
        $token = $this->encrypt($url);

        $baseUrl = 'http://tool.manmanbuy.com/history.aspx?action=gethistory&token=' . $token .
            '&url=' . urlencode($url);
        $rsp = Http::get($baseUrl);
        $headers = $rsp->headers();
        $contentType = $headers['Content-Type'];
        $arr = explode('; ', $contentType[0]);
        $charset = 'utf-8';
        foreach ($arr as $a) {
            if (strpos($a, 'charset') !== false) {
                $charset = explode('=', $a)[1];
            }
        }
        $rsp = mb_convert_encoding($rsp, 'utf-8', $charset);
        $rsp = json_decode($rsp, true);
        if (!$rsp || $rsp['bjid'] == 1030614958) {
            return [];
        }
        $priceStr = $rsp['datePrice'];
        $lowerDate = $rsp['lowerDate'];
        $title = $rsp['spName'];
        $items = $this->str2array($priceStr);
        $last7day = strtotime('-7 day');
        $last30day = strtotime('-30 day');
        $results = [];
        $lowest = $highest = $items[count($items) - 1];
        foreach ($items as $item) {
            $time = strtotime($item[0]);
            if ($time > $last30day) {
                if ($item[1] <= $lowest[1]) {
                    $lowest = $item;
                }
                if ($item[1] >= $highest[1]) {
                    $highest = $item;
                }
                if ($time > $last7day) {
                    $results []= $item;
                }
            }
        }
        /**
         * 生成价格折线图
         */
        // $x = $y = [];
        // foreach ($items as $item) {
        //     if (count($item) == 3) {
        //         $datetime = $item[0];
        //         $date = explode(' ', $datetime)[0];
        //         $price = $item[1];
        //         $desc = $item[2];
        //         $x[] = $date;
        //         $y[] = $price;
        //     }
        // }
        // $x = array_slice($x, -15);
        // $y = array_slice($y, -15);
        // $chart = new Chart($title, $x, $y, ['cs']);
        // $chart->paintLineChart();
        return [
            'lowestDate' => $this->formatLowestDate($lowerDate),   // 商品历史最低价格日期
            'lowestPrice' => $rsp['lowerPrice'],              // 商品历史最低价格
            'title' => $title,                        // 商品标题
            'website' => $rsp['siteName'],                        // 商品标题
            // 'changPriceRemark' => $rsp['changPriceRemark'],   // 价格涨幅
            // 'changePriceCount' => $rsp['changePriceCount'],   // 价格变更次数
            'avatar' => $rsp['spPic'],                        // 商品主图
            'url' => $rsp['spUrl'],                           // 商品主图
            // 'discount' => $rsp['ZheKouCount'],                // 折扣次数
            'price' => $rsp['currentPrice'],                  // 当前价格
            'lowest' => $lowest[0] . ' ￥' . $lowest[1],          // 近30天最低价
            'highest' => $highest[0] . ' ￥' . $highest[1],       // 近30天最高价
            'items' => $results,           // 近7天价格
        ];
    }

    /**
     * 将价格字符串转数组
     * @param $str
     * @return array
     */
    private function str2array($str)
    {
        $items = explode('],', $str);
        $results = [];
        foreach ($items as $item) {
            if (strpos($item, ']') === false) {
                $item = $item . ']';
            }
            $result = json_decode($item);
            $result[0] = date('Y-m-d', $result[0] / 1000);
            $results[] = $result;
        }
        return $results;
    }

    /**
     * 格式化最低价格的日期（/Date(1541520000000+0800)/）
     * @param $str
     * @return false|string
     */
    private function formatLowestDate($str)
    {
        $str = str_replace('/Date(', '', $str);
        $str = str_replace(')/', '', $str);
        $str = str_replace('-0000', '', $str);
        $items = explode('+', $str);
        return date('Y-m-d', $items[0] / 1000);
    }
}
